#pragma once
#include <iostream>
#include <string>
#include <functional>
#include <unistd.h>
#include <pthread.h>
using namespace std;

namespace ThreadModle
{
    //函数类型：没有参数，返回值void
    static int number = 1;//线程的个数
    enum class TSTATUS
    {
        NEW,
        RUNNING,
        STOP
    };

    template <typename T>
    class Thread
    {
        using func_t = function<void(T)>;
    private:
        //定位为static，前面就没有this指针了
        static void* Routine(void* args)
        {
            //这里不能直接使用func，因为前面没有this指针。
            Thread<T> *t = static_cast<Thread<T>*>(args);
            t->_func(t->_data);
            t->_status = TSTATUS::RUNNING;
            return (void*)0;
        }
    public:
        //构造函数
        Thread(func_t func,T data):_func(func),_data(data),_status(TSTATUS::NEW),_joinable(true)
        {
            _name = "Thread-"+to_string(number++);
        }
        //线程启动
        bool Start()
        {
            //当状态不是start的时候，stop和new都可以启动
            if(_status != TSTATUS::RUNNING)
            {
                int n = pthread_create(&_tid,nullptr,Routine,this);
                if(n != 0) return false;
            }
            return true;
        }
        void Stop()//线程结束了不代表thread对象结束了
        {
            //
            if(_status == TSTATUS::RUNNING)
            {

            }
        }
        //等待线程
        bool Join()
        {
            //
            if(_joinable)
            {
                int n = ::pthread_join(_tid,nullptr);
                if(n != 0) return false;
                _status = TSTATUS::STOP;
            }
            return true;
        }
        //设置自己是否是分离的
        void EnableDetach()
        {

        }
        //设置等待
        void EnableJoinable()
        {

        }
        //析构函数
        ~Thread()
        {

        }
        //
    private:
        string _name;//线程名字
        pthread_t _tid;//线程tid
        pid_t _pid;//进程pid
        bool _joinable;//是否是分离的，默认不是分离的
        func_t _func;//线程的任务
        TSTATUS _status;
        T _data;//数据
    };
}